# 编码解码
import json
# 转换时间字符串 对象
from datetime import datetime

# 分页
from django.core.paginator import Paginator
# 数据库
from django.db.models import Q
# 响应类
from django.http import HttpResponse, JsonResponse
from django.utils.formats import date_format, time_format
# 模型类
from idx.models import *
# from idx.util import *

from idx.utils.Result import Result
from idx.utils.Request import Request
from idx.utils.Pages import Pages


# from django.shortcuts import render

def register(request):
    msg = '注册成功'
    code = '200'
    data = {}
    if request.method == 'POST':
        # request.body (bytes object)
        # decode to string
        request_args = json.loads(request.body.decode())
        req_arg_username = request_args['username']
        req_arg_password = request_args['password']
        req_arg_role = request_args['role']
        ds = User.objects.filter(username=req_arg_username)
        # 没有重复用户  注册成功
        if ds.count() == 0:
            # genderate user record and validate
            # user = User(username=req_arg_username, password=req_arg_password, role=req_arg_role)
            # test role field should be 1 - 3
            # user.clean_fields()

            User.objects.create(username=req_arg_username,
                                password=req_arg_password,
                                role=req_arg_role)

            # if register user role == 1. user, create user info
            # only bind user record, other values are default 'blank'/0
            if request_args['role'] == '用户':
                birthday = datetime.strptime('2000-01-01', '%Y-%m-%d').date()
                UserInfo.objects.create(user=ds[0], birthday=birthday)

                # update user register num
                if UserRegisterNum.objects.filter(
                        day=datetime.now().date()).count() == 0:
                    UserRegisterNum.objects.create()
                else:
                    register_record = UserRegisterNum.objects.get(
                        day=datetime.now().date())
                    register_record.amount += 1
        else:
            msg = '账户已存在'
            code = '501'
            data = {}

    result = Result(code, msg, data)

    # return JsonResponse(result.serialize())
    return HttpResponse(json.dumps(result.serialize()),
                        headers={'Access-Control-Allow-Origin': '*'})


def login(request):
    code = '200'
    msg = ''
    data = {}
    if request.method == 'POST':
        user = json.loads(request.body.decode())
        ds = User.objects.filter(username=user['username'])
        # user not exist
        if ds.count() == 0:
            msg = '用户不存在'
            code = '501'
        # user exist
        else:
            if ds[0].password == user['password']:
                data = {
                    'id': ds[0].id,
                    'username': ds[0].username,
                    'role': ds[0].role
                }
            else:
                code = '502'
                msg = '密码错误'

    result = Result(code, msg, data)
    return HttpResponse(json.dumps(result.serialize()),
                        headers={'Access-Control-Allow-Origin': '*'})


# ================================ user ===================================


# 支付
def user_pay(request):
    result = Result('200','',{})
    request_data = json.loads(request.body)
    code = '200'
    msg = '支付成功'
    data = {}

    user = User.objects.get(id=request_data['user_id'])
    pay = Pay.objects.get(id=request_data['pay_id'])
    order = pay.order
    hotel = order.hotel
    room = order.room
    room_num = order.room_num
    origin_price = pay.price
    cut_price = 0
    final_price = 0

    # 线上支付
    if user.role == '用户':
        # 使用了优惠券
        if request_data['coupon_id'] != 0:
            coupon = CouponEntity.objects.get(id=request_data['coupon_id'])
            coupon.status = '已使用'
            coupon.save()
            cut_price = coupon.coupon_template.discount
        final_price = origin_price - cut_price
        userinfo = UserInfo.objects.get(user=user)
        # 看看钱包
        wallet = userinfo.wallet
        # 钱不够
        if wallet < final_price:
            result.code = '501'
            result.msg = '余额不足'
        # 够了
        else:
            rest_money = wallet - final_price
            # 扣钱
            userinfo.wallet = rest_money
            userinfo.save()
            # 支付完成 更改订单状态 '已预约' 支付记录状态 '已支付'
            order.status = '已预约'
            order.save()
            pay.status = '已支付'
            pay.price = final_price
            pay.save()
            # # update room num
            # room.rest -= room_num
            # room.save()
    # 线下支付 更改订单状态 '已预约' 创建支付记录 '已支付'
    else:
        final_price = origin_price - cut_price
        order = pay.order
        order.status = '已预约'
        order.save()
        pay.price = final_price
        pay.status = '已支付'
        pay.save()
        # # update room num
        # room.rest -= room_num
        # room.save()

    # update daily income
    if DailyIncome.objects.filter(day=datetime.now().date(), hotel=hotel).count() == 0:
        DailyIncome.objects.create(hotel=hotel, income=final_price)
    else:
        daily_income = DailyIncome.objects.get(day=datetime.now().date(), hotel=hotel)
        daily_income.income += final_price
        daily_income.save()
    return result.http_response()


# change password
def user_change_password(request):
    code = '200'
    msg = '修改成功'
    request_data = json.loads(request.body)
    print(request_data)

    user_id = request_data['user_id']

    user = User.objects.get(id=user_id)

    if request_data['old_password'] != user.password:
        code = '501'
        msg = '旧密码错误'
    else:
        user.password = request_data['new_password']
        user.save()

    # 更新方法 2

    # u = User.objects.get(username=uname)
    # pwd = request.POST['password']
    # User.objects.create(username=uname,password=pwd,instance=u)

    result = Result(code, msg, {})
    return HttpResponse(json.dumps(result.serialize()),
                        headers={'Access-Control-Allow-Origin': '*'})


def user_info_list(request, user_id):
    code = '501'
    msg = 'no data'
    user = User.objects.get(id=user_id)
    data = {}

    # exist
    if UserInfo.objects.filter(user=user).count() != 0:
        code = '200'
        msg = 'ojbk'
        userinfo = UserInfo.objects.get(user=user)
        data = {
            'name': userinfo.name,
            'birthday': date_format(userinfo.birthday, 'Y-m-d'),
            'gender': userinfo.gender
        }
    # ======================================= to be deleted ==============================
    # # not exist, create userinfo
    # else:
    # 	birthday = datetime.strptime('2000-01-01', '%Y-%m-%d').date()
    # 	UserInfo.objects.create(user=ds[0], birthday=birthday)
    # ======================================= to be deleted ==============================
    result = Result(code, msg, data)
    return HttpResponse(json.dumps(result.serialize()),
                        headers={'Access-Control-Allow-Origin': '*'})


def user_info_list_admin(request):
    code = '501'
    msg = 'no data'
    userinfo_list = []

    request_args = json.loads(request.body.decode())
    print('------- admin get userinfo list -----------')
    print(request_args)

    page_id = 1
    if request_args.get('page_id'):
        page_id = request_args['page_id']
    page_size = 5
    if request_args.get('page_size'):
        page_size = request_args['page_size']

    user_ds = User.objects.filter(role='用户')
    pages = Paginator(user_ds, page_size)
    page = pages.get_page(page_id)
    for user in page:
        code = '200'
        msg = 'ojbk'
        userinfo = user.userinfo
        birthday = date_format(userinfo.birthday, 'Y-m-d')
        userinfo_list.append({
            'user_id': user.id,
            'username': user.username,
            'password': user.password,
            'name': userinfo.name,
            'gender': userinfo.gender,
            'birthday': birthday,
            'wallet': userinfo.wallet,
            'point': userinfo.point
        })

    data = {
        'userinfo_list': userinfo_list,
        'page_amount': pages.num_pages,
        'item_amount': user_ds.count()
    }
    print(data)
    result = Result(code, msg, data)
    return HttpResponse(json.dumps(result.serialize()),
                        headers={'Access-Control-Allow-Origin': '*'})


def user_info_update(request):
    # get request parameters
    request_data = json.loads(request.body.decode())
    print(request_data)
    user_id = request_data.get('user_id')
    user = User.objects.get(id=user_id)
    name = request_data.get('name')
    gender = request_data.get('gender')
    birthday = datetime.strptime(request_data.get('birthday'),
                                 '%Y-%m-%d').date()

    # check userinfo if exist

    # if not exist, create user info record
    if UserInfo.objects.filter(user=user).count() == 0:
        UserInfo.objects.create(user=user,
                                name=name,
                                gender=gender,
                                birthday=birthday)
    else:
        # update userinfo
        userinfo = UserInfo.objects.get(user=User.objects.get(id=user_id))
        userinfo.name = name
        userinfo.gender = gender
        userinfo.birthday = birthday
        userinfo.save()
    result = Result('200', '修改成功', {})
    return HttpResponse(json.dumps(result.serialize()),
                        headers={'Access-Control-Allow-Origin': '*'})


# ============================ user - collection ================================


def user_collect_hotel(request):
    code = '200'
    msg = '收藏成功'
    request_data = json.loads(request.body)
    user_id = request_data['user_id']
    hotel_id = request_data['hotel_id']
    # 不能重复收藏
    if Collection.objects.filter(
            user=User.objects.get(id=user_id),
            hotel=Hotel.objects.get(id=hotel_id)).count() != 0:
        code = '501'
        msg = '已收藏'
    else:
        Collection.objects.create(user=User.objects.get(id=user_id),
                                  hotel=Hotel.objects.get(id=hotel_id))
    result = Result(code, msg, {})
    return HttpResponse(json.dumps(result.serialize()),
                        headers={'Access-Control-Allow-Origin': '*'})


# get
def user_collection_list(request):
    code = '200'
    msg = '查询成功'
    data = {}
    request_args = json.loads(request.body.decode())
    print(request_args)
    if request_args.get('username'):
        username = request_args['username']

        page_size = 5
        if request_args.get('page_size'):
            page_size = request_args['page_size']
        page_id = 1
        if request_args.get('page_id'):
            page_id = request_args['page_id']

        collect_list = []

        if User.objects.filter(username=username).count()==0:
            msg = 'no user matched'
            result = Result(code, msg, data)
            return HttpResponse(json.dumps(result.serialize()), headers={'Access-Control-Allow-Origin': '*'})


        collect_ds = Collection.objects.filter(user=User.objects.get(username=username))
        if collect_ds.count() == 0:
            # code = '501'
            msg = '没有收藏酒店'
        else:
            # search hotel contains `hotel_name` in user collection
            if request_args.get('hotel_name') != '':
                collect_ds = Collection.objects.filter(
                    user=User.objects.get(username=username),
                    hotel__name__contains=request_args.get('hotel_name'))

            if collect_ds.count() == 0:
                # code = '502'
                msg = '没有搜索到相关酒店'
            else:
                collect_ds = collect_ds.order_by('-id')
            # paginator
            pages = Paginator(collect_ds, page_size)
            page = pages.get_page(page_id)
            for collect in page:
                collect_list.append({
                    'hotel_id': collect.hotel.id,
                    'hotel_name': collect.hotel.name,
                    'level': collect.hotel.level,
                    'location': collect.hotel.location,
                    'intro': collect.hotel.intro
                })
            data = {
                'collection_list': collect_list,
                "page_total": pages.num_pages,
                "item_amount": collect_ds.count()
            }
    result = Result(code, msg, data)
    return HttpResponse(json.dumps(result.serialize()),
                        headers={'Access-Control-Allow-Origin': '*'})


def user_collection_cancel(request):
    code = '200'
    msg = '取消成功'
    request_data = json.loads(request.body)
    user_id = request_data['user_id']
    hotel_id = request_data['hotel_id']
    record = Collection.objects.filter(user=User.objects.get(id=user_id),
                                       hotel=Hotel.objects.get(id=hotel_id))[0]
    record.delete()
    result = Result(code, msg, {})
    return HttpResponse(json.dumps(result.serialize()),
                        headers={'Access-Control-Allow-Origin': '*'})


# =========================== user - points ==================================


# add user's point after payment
# relative models:
# 1. Pay.point
# 2. UserInfo.point ( User.role = user )
# 3. PointIncome.point
def user_points_add(request):
    code = '200'
    msg = '增加成功'
    request_data = json.loads(request.body)
    print(request_data)
    pay_record = Pay.objects.get(id=request_data['pay_id'])
    point_amount = request_data['point_amount']

    # update pay record's point
    pay_record.point_amount = point_amount
    pay_record.save()

    # update user's point
    userinfo = UserInfo.objects.get(user__id=pay_record.user.id)
    userinfo.point += point_amount
    userinfo.save()

    # create point income record
    user = userinfo.user
    Point.objects.create(user=user,
                         pay=pay_record,
                         point_amount=point_amount,
                         couponEntity=pay_record.coupon)
    result = Result(code, msg, {})
    return HttpResponse(json.dumps(result.serialize()),
                        headers={'Access-Control-Allow-Origin': '*'})


# get
def user_points_list(request):
    result = Result('200', '查询成功', {})

    request_args = json.loads(request.body.decode())

    # none data if arg `user_id` not provided
    if request_args.get('username'):
        username = request_args['username']
        page_size = 5
        if request_args.get('page_size'):
            page_size = request_args['page_size']
        page_id = 1
        if request_args.get('page_id'):
            page_id = request_args['page_id']

        # # compute page range
        # page_min = (page_id - 1) * page_size
        # page_max = page_id * page_size - 1
        # page_cursor = 0

        # print('range:', page_min, '-', page_max)

        if User.objects.filter(username=username).count()==0:
            result.code = '501'
            result.msg = 'no matched user'
        else:
            user = User.objects.get(username=username)
            if user.role == '用户':
                user_info = UserInfo.objects.get(user=user)
                # time type amount
                detail_list = []

                point_ds = Point.objects.filter(user=user).order_by('-time')
                if point_ds.count() == 0:
                    result.msg = 'no point record'
                    return result.http_response()
                
                # paginator
                pages = Pages(point_ds, page_size)
                page = pages.get(page_id)
                for item in page:
                    # convert time object to string
                    datetimeobj = item.time
                    format_date = date_format(datetimeobj, 'Y-m-d')
                    format_time = time_format(datetimeobj.time(), 'H:i')
                    format_datetime = format_date + " " + format_time

                    # point type +/-
                    point_type = '+'
                    if CouponEntity.objects.filter(point=item).count() > 0:
                        point_type = '-'
                    detail_list.append({
                        'time': format_datetime,
                        'type': point_type,
                        'amount': item.point_amount,
                        # # point id
                        # 'point_id': item.id
                    })
                data = {
                    'points': user_info.point,
                    'points_detail': detail_list,
                    "page_total": pages.page_total,
                    "item_amount": point_ds.count()
                }
                result.data = data
    return HttpResponse(json.dumps(result.serialize()),
                        headers={'Access-Control-Allow-Origin': '*'})


# =========================== user - wallet ======================================

# add


def user_wallet_recharge(request):
    code = '200'
    msg = '充值成功'
    request_data = json.loads(request.body)
    user = User.objects.get(id=request_data['user_id'])
    userinfo = UserInfo.objects.get(user=user)
    recharge_amount = float(request_data['amount'])

    # update user wallet
    userinfo.wallet += recharge_amount
    userinfo.save()
    # create recharge record
    Recharge.objects.create(user=user, money=recharge_amount)
    result = Result(code, msg, {})
    return HttpResponse(json.dumps(result.serialize()),
                        headers={'Access-Control-Allow-Origin': '*'})


# get
def user_wallet_detail(request):
    code = '200'
    msg = '查询成功'
    data = {}
    # time type amount
    detail_list = []

    request_args = json.loads(request.body.decode())
    print(request_args)
    # none data if no user_id arg
    if request_args.get('username'):
        username = request_args['username']

        if User.objects.filter(username=username).count()==0:
            code = '501'
            msg = 'no user matched id'
        else:
            user = User.objects.get(username=username)

            if user.role == '用户':
                userinfo = UserInfo.objects.get(user=user)

                page_size = 5
                if request_args.get('page_size'):
                    page_size = request_args['page_size']
                page_id = 1
                if request_args.get('page_id'):
                    page_id = request_args['page_id']

                # compute page range
                page_min = (page_id - 1) * page_size
                page_max = page_id * page_size - 1
                page_cursor = 0
                print("page min:", page_min)
                print("page max:", page_max)

                # 查询充值表和支付记录 时间降序
                user_pay_ds = Pay.objects.filter(user=user).order_by('-pay_time')
                user_recharge_ds = Recharge.objects.filter(user=user).order_by('-time')
                if user_pay_ds.count() == 0 and user_recharge_ds.count() == 0:
                    # code = '501'
                    msg = '没有相关记录'
                else:
                    pay_index = 0
                    recharge_index = 0

                    # all not none
                    if user_pay_ds.count() != 0 and user_recharge_ds.count() != 0:
                        # all not none
                        while pay_index < user_pay_ds.count(
                        ) and recharge_index < user_recharge_ds.count():
                            # pay
                            if user_pay_ds[pay_index].pay_time > user_recharge_ds[
                                    recharge_index].time:
                                # if page_cursor in range
                                if page_cursor >= page_min and page_cursor <= page_max:
                                    print("add pay record")
                                    datetimeobj = user_pay_ds[pay_index].pay_time
                                    format_date = date_format(datetimeobj, 'Y-m-d')
                                    format_time = time_format(datetimeobj.time(),
                                                              'H:i')
                                    format_datetime = format_date + " " + format_time
                                    detail_list.append({
                                        'time':
                                        format_datetime,
                                        'type':
                                        'pay',
                                        'amount':
                                        user_pay_ds[pay_index].price
                                    })
                                pay_index += 1
                            # recharge
                            else:
                                if page_cursor >= page_min and page_cursor <= page_max:
                                    print("add recharge record")
                                    datetimeobj = user_recharge_ds[recharge_index].time
                                    format_date = date_format(datetimeobj, 'Y-m-d')
                                    format_time = time_format(datetimeobj.time(),
                                                              'H:i')
                                    format_datetime = format_date + " " + format_time
                                    detail_list.append({
                                        'time':
                                        format_datetime,
                                        'type':
                                        'recharge',
                                        'amount':
                                        user_recharge_ds[recharge_index].money
                                    })
                                recharge_index += 1
                            page_cursor += 1
                            print("cursor index: ", pay_index)
                    # if pay or recharge no data
                    elif user_pay_ds.count() == 0:
                        print('user recharge ds:', user_recharge_ds.count())
                        # return recharge record
                        for item in user_recharge_ds:
                            datetimeobj = user_recharge_ds[recharge_index].time
                            format_date = date_format(datetimeobj, 'Y-m-d')
                            format_time = time_format(datetimeobj.time(), 'H:i')
                            format_datetime = format_date + " " + format_time
                            detail_list.append({
                                'time':
                                format_datetime,
                                'type':
                                'recharge',
                                'amount':
                                user_recharge_ds[recharge_index].money
                            })
                    elif user_recharge_ds.count() == 0:
                        print('user pay ds:', user_pay_ds.count())
                        # return pay record
                        for item in user_pay_ds:
                            datetimeobj = user_pay_ds[pay_index].pay_time
                            format_date = date_format(datetimeobj, 'Y-m-d')
                            format_time = time_format(datetimeobj.time(), 'H:i')
                            format_datetime = format_date + " " + format_time
                            detail_list.append({
                                'time': format_datetime,
                                'type': 'pay',
                                'amount': user_pay_ds[pay_index].price
                            })

                page_total = 0
                if (user_pay_ds.count() + user_recharge_ds.count()) % page_size == 0:
                    page_total = (user_pay_ds.count() +
                                  user_recharge_ds.count()) / page_size
                else:
                    page_total = (user_pay_ds.count() +
                                  user_recharge_ds.count()) / page_size + 1
                data = {
                    'balance': userinfo.wallet,
                    'detail': detail_list,
                    "page_total": page_total,
                    "item_amount": user_pay_ds.count() + user_recharge_ds.count()
                }
                print(user_pay_ds.count() + user_recharge_ds.count())
                print(data)

    result = Result(code, msg, data)
    return HttpResponse(json.dumps(result.serialize()),
                        headers={'Access-Control-Allow-Origin': '*'})


# ========================= user - comment ===================================


# 用户查看评论
def user_comment_list(request):
    uname = request.session['username']
    cmt = comment.objects.filter(user__username__exact=uname)
    pages = Paginator(cmt, 5)
    page_number = 1
    if 'page' in request.GET:
        page_number = request.GET['page']
    page = pages.get_page(page_number)
    return render(request, 'ucmts.html', {'p': page})


# ========================= user - activity ===================================

def user_activity(request):
    request_data = Request(request)

# =================================== hotel ===================================


# 查询酒店 分页
def hotel_search(request):
    hotel_list = []
    msg = '查询成功'
    code = '200'
    data = {}

    if request.method == 'POST':
        # default paginator args
        page_id = 1
        page_size = 5
        request_args = json.loads(request.body.decode())

        print(request_args)

        if request_args.get('page_size'):
            page_size = request_args.get('page_size')
        if request_args.get('page_id'):
            page_id = request_args.get('page_id')

        # =============== admin get hotel request list to audit ===============
        if request_args.get('admin_id'):

            # get all hotel requests by default
            hotel_ds = Hotel.objects.all()
            # only get ready to audited hotels
            if request_args.get('hotel_status') == 0:
                hotel_ds = Hotel.objects.filter(hotelrequest__status='待审核')
            elif request_args.get('hotel_status') == 1:
                hotel_ds = Hotel.objects.filter(hotelrequest__status='已通过')

            if hotel_ds.count() == 0:
                code = '501'
                msg = '没有相关记录'
            else:
                # paginator
                pages = Paginator(hotel_ds, page_size)
                page = pages.get_page(page_id)

                # return data: hotel_list (hotel requests data)
                for hotel in page:
                    hotel_request = hotel.hotelrequest
                    hotel_list.append({
                        "id": hotel.id,
                        "name": hotel.name,
                        "location": hotel.location,
                        "intro": hotel.intro,
                        "level": hotel.level,
                        "price": hotel.min_price,
                        "status": hotel_request.status
                    })
                data = {
                    "hotel_list": hotel_list,
                    "page_total": pages.num_pages,
                    "item_amount": hotel_ds.count()
                }
            result = Result(code, msg, data)
            return HttpResponse(json.dumps(result.serialize()),
                                headers={'Access-Control-Allow-Origin': '*'})

        # ================ others query hotels ====================

        else:
            # # query all hotels by default
            # #back/idx/views.py if request.audited == True will only get audited hotels
            # audited = False
            # if request_args.get('audited'):
            # 	audited = request_args.get('audited')
            # if audited:
            # 	hotel_ds = hotel_ds.filter(status=2)

            # get hotel which business has
            if request_args.get('business_id'):
                # only get audited hotels
                if request_args.get('audited'):
                    hotel_ds = Hotel.objects.filter(
                        admin__id=request_args.get('business_id'),
                        hotelrequest__status='已通过')
                else:
                    hotel_ds = Hotel.objects.filter(
                        admin__id=request_args.get('business_id'))
            else:
                # if ( bool(request_args.get('location')) | bool(request_args.get('keyword')) ) & (request_args.get('level')=='' ):
                # 	hotel_ds = Hotel.objects.filter(location=request_args.get('location'), intro__contains=request_args.get('keyword'))
                # if request_args.get('level')!='':
                # 	hotel_ds = Hotel.objects.filter(location__contains=request_args.get('location'), intro__contains=request_args.get('keyword'), level__in=request_args.get('level'))
                # if ( request_args.get('location')=='' ) & ( request_args.get('keyword')=='' ) & ( (request_args.get('level')=='') | (request_args.get('level')==[]) ):
                # 	hotel_ds = Hotel.objects.all()

                print("user search hotel...")
                if (request_args.get('level')
                        != '') & (request_args.get('level') != []):
                    print("level not None, <list>")
                    hotel_ds = Hotel.objects.filter(
                        location__contains=request_args.get('location'),
                        intro__contains=request_args.get('keyword'),
                        level__in=request_args.get('level'))
                    if request_args.get('audited') == True:
                        print("only get audited hotel")
                        hotel_ds = Hotel.objects.filter(
                            location__contains=request_args.get('location'),
                            intro__contains=request_args.get('keyword'),
                            level__in=request_args.get('level'),
                            hotelrequest__status='已通过')
                else:
                    print("level not choose, ''")
                    hotel_ds = Hotel.objects.filter(
                        location__contains=request_args.get('location'),
                        intro__contains=request_args.get('keyword'))
                    if request_args.get('audited') == True:
                        print("only get audited hotel")
                        hotel_ds = Hotel.objects.filter(
                            location__contains=request_args.get('location'),
                            intro__contains=request_args.get('keyword'),
                            hotelrequest__status='已通过')

                if request_args.get('hotel_name'):
                    hotel_ds = Hotel.objects.filter(
                        name__contains=request_args.get('hotel_name'))

            # no hotels
            if hotel_ds.count() == 0:
                msg = '没有找到相关酒店'
                code = '501'
                result = Result(code, msg, {})
                return HttpResponse(
                    json.dumps(result.serialize()),
                    headers={'Access-Control-Allow-Origin': '*'})
            else:
                hotel_ds.order_by('-id')
                pages = Paginator(hotel_ds, page_size)
                page = pages.get_page(page_id)
                for hotel in page:
                    hotel_request = HotelRequest.objects.get(hotel=hotel)
                    hotel_list.append({
                        'id': hotel.id,
                        'name': hotel.name,
                        'location': hotel.location,
                        'intro': hotel.intro,
                        'level': hotel.level,
                        "price": hotel.min_price,
                        "status": hotel_request.status
                    })
                data = {
                    'hotel_list': hotel_list,
                    'page_total': pages.num_pages,
                    "item_amount": hotel_ds.count()
                }
    result = Result(code, msg, data)
    return HttpResponse(json.dumps(result.serialize()),
                        headers={'Access-Control-Allow-Origin': '*'})


# 酒店详情

# url: `hotel_detail/<hotel_id>/`
# method: get


# 返回数据 res.data
# - 酒店信息 hotel
#	 - 酒店id id
#	 - 酒店名称 name
#	 - 地址 location
#	 - 简介 intro
#	 - 级别 level
#	 - 酒店图片路径 url
#	 - 起步价 price
# - 房间信息 room
#	 - 房间类型 roomtype
#	 - 价格 price
#	 - 剩余房间数 rest
# - 评价 comment
#	 - 用户名 username
#	 - 评价内容 context
#	 - 评价时间 time
def hotel_detail(request, htid):
    data = {}
    code = 200
    msg = '查询成功'
    room_list = []
    comment_list = []
    hotel_data = {}

    hotel_ds = Hotel.objects.filter(id=htid)
    if hotel_ds.count() == 0:
        msg = '没有找到相关酒店'
        code = '501'
    # hotel exist
    else:
        hotel = hotel_ds[0]
        room_ds = Room.objects.filter(hotel=htid)
        comment_ds = Comment.objects.filter(order__hotel__id=htid)

        for room in room_ds:
            room_list.append({
                'roomtype': room.roomtype,
                'price': room.price,
                'rest': room.rest
            })
        for comment in comment_ds:
            formatdate = date_format(comment.time, 'Y-m-d')
            formattime = time_format(comment.time.time(), 'H:i')
            formatdatetime = formatdate + ' ' + formattime
            comment_list.append({
                'content': comment.content,
                'username': comment.user.username,
                'time': formatdatetime
            })
        hotel_data = {
            'id': hotel.id,
            'name': hotel.name,
            'location': hotel.location,
            'intro': hotel.intro,
            'level': hotel.level,
            'url': hotel.url.url,
            "price": hotel.min_price
        }
    data = {'hotel': hotel_data, 'room': room_list, 'comment': comment_list}
    result = Result(code, msg, data)
    return HttpResponse(json.dumps(result.serialize()),
                        headers={'Access-Control-Allow-Origin': '*'})


# 预约酒店 生成订单和支付记录
def hotel_booking(request):
    msg = '预约成功，待支付'
    code = '200'
    data = {}

    request_data = json.loads(request.body.decode())
    print("hotel_booking :: args - user_id:", request_data.get('user_id'))
    user_id = request_data.get('user_id')
    hotel_id = request_data.get('hotel_id')
    room_type = request_data.get('room_type')

    user = User.objects.get(id=user_id)
    hotel = Hotel.objects.get(id=hotel_id)
    room = Room.objects.filter(hotel=hotel, roomtype=room_type)[0]
    if room.rest<request_data.get('room_num'):
        msg = '房间不足'
        code = '501'
        result = Result(code, msg, {})
        return result.http_response()

    room.rest -= request_data.get('room_num')
    room.save()

    # 生成订单，默认待支付，下单时间自动生成
    order = Order.objects.create(
        user=user,
        hotel=hotel,
        room=room,
        room_num=request_data.get('room_num'),
        name=request_data.get('name'),
        id_card=request_data.get('id_card'),
        phone=request_data.get('phone'),
        email=request_data.get('email'),
        price=request_data.get('price'),
        # # 转换时间字符串
        checkin_date=datetime.strptime(request_data.get('checkin_date'),
                                       '%Y-%m-%d').date(),
        checkout_date=datetime.strptime(request_data.get('checkout_date'),
                                        '%Y-%m-%d').date(),
        pre_reachtime=datetime.strptime(request_data.get('time'),
                                        '%H:%M').time(),
        note=request_data.get('note'),
        stay_days=request_data.get('stay_days'))

    # 生成支付记录 默认未支付 优惠券不填，支付时间自动生成（记录更新时间）

    # 先判读 user 身份，若为前台则为空，用于判断线上或线下支付
    if user.role != '用户':
        user = None
    pay = Pay.objects.create(user=user,
                             coupon=None,
                             order=order,
                             price=order.price)

    # update OrderNumByRoomType

    # new record, init num '1'
    if OrderNumByRoomType.objects.filter(hotel=hotel,
                                         roomtype=room.roomtype).count() == 0:
        OrderNumByRoomType.objects.create(hotel=hotel, roomtype=room.roomtype)
    else:
        # add 1
        ordernum_roomtype = OrderNumByRoomType.objects.get(
            hotel=hotel, roomtype=room.roomtype)
        # num = ordernum_roomtype.count
        ordernum_roomtype.count += 1
        ordernum_roomtype.save()

    data = {'pay_id': pay.id}
    result = Result(code, msg, data)
    return HttpResponse(json.dumps(result.serialize()),
                        headers={'Access-Control-Allow-Origin': '*'})


# 添加酒店
def hotel_add(request):
    code = '200'
    msg = ''
    request_data = json.loads(request.body)
    print(request_data)

    # hotel_img = request.FILES.get('url')

    # ================ business apply for add hotel =========================
    if request_data.get('business_id'):
        location = request_data['location']
        hotel_name = request_data['name']
        business = User.objects.filter(id=request_data.get('business_id'))[0]

        # ok, my fualt... you can be two
        # 不能同名
        # if Hotel.objects.filter(name=request_data['name']).count()!= 0:
        # 	code = '501'
        # 	msg = '酒店已存在'
        # else:

        # xxxxxxxxxxx wait for front end xxxxxxxxxxxxx
        # # save hotel img
        # img = request.FILE.get['url']
        # img_name = hotel_name + '.' + img.name.split('.')[-1]

        # img_content = img.chunks()

        # # only accept jpg
        # # if img_name.split('.')[-1]!= 'jpg':
        # # 	code = '501'
        # # 	msg = '图片格式不正确'
        # # else:
        # path = "/static/images/hotels/%s"%(img_name)
        # # /idx + path: 项目根目录开始找app名 "idx" + path
        # # wb: write & byte 写模式写入二进制数据
        # with open("idx"+path,"wb") as fs:
        # 	for t in img_content:
        # 		fs.write(t)
        # xxxxxxxxxxxxxx wait for front end xxxxxxxxxxxxx

        # create hotel record
        hotel = Hotel.objects.create(
            admin=business,
            name=hotel_name,
            level=request_data['level'],
            location=request_data['location'],
            # url='images/hotels/'+hotel_name,
            intro=request_data['intro'],
            min_price=request_data['price'])

        # create hotel request record for business
        hotel_request = HotelRequest(user=business, hotel=hotel, status='待审核')
        hotel_request.save()
        msg = '申请成功'

    # ================== admin audit hotel ====================
    elif request_data.get('admin_id'):
        hotel = Hotel.objects.get(id=request_data['hotel_id'])
        location = hotel.location
        hotel_request = HotelRequest.objects.get(hotel=hotel)
        admin_audit = request_data['status']
        if admin_audit == 2:
            admin_audit = '已通过'
        elif admin_audit == 3:
            admin_audit = '已拒绝'
        hotel_request.status = admin_audit
        hotel_request.save()
        msg = '审核成功'

        # add a new area
        if Area.objects.filter(name=location).count() != 0:
            Area.objects.create(name=location)

    result = Result(code, msg, {})
    return HttpResponse(json.dumps(result.serialize()),
                        headers={'Access-Control-Allow-Origin': '*'})


def img_upload(request, hotel_id):
    # img_byte = byte_to_img(request.body)
    img_data = request.FILES.get('url')
    print('receive img data, type =', type(img_data))

    hotel = Hotel.objects.get(id=hotel_id)
    hotel.url = img_data
    hotel.save()

    # with open('images/hotels/'+hotelname+'.'+ext, 'wb') as f:
    # 	for t in img_data.chunks():
    # 		# f.write(bytes(t))
    # 		f.write(t)
    result = Result('200', 'upload success', {})
    return HttpResponse(json.dumps(result.serialize()),
                        headers={'Access-Control-Allow-Origin': '*'})


def hotel_image(request, hotel_id):
    hotel = Hotel.objects.get(id=hotel_id)
    imgpath = hotel.url.url[1:]
    imgname = imgpath.split('/')[-1]
    print('hotel img path:', imgpath)
    with open(imgpath, 'rb') as f:
        file_content = f.read()
        response = HttpResponse(file_content, content_type='image/*')
        response[
            'Content-Disposition'] = 'attachment; filename="' + imgname + '"'
        return response


def hotel_update(request):
    code = '200'
    msg = '修改成功'

    # request args
    request_data = json.loads(request.body)
    hotel_name = request_data['name']

    # not allow same name
    same_name_hotel_ds = Hotel.objects.filter(name=hotel_name)
    exist = False
    if same_name_hotel_ds.count() != 0:
        for item in same_name_hotel_ds:
            if item.id != request_data['hotel_id']:
                exist = True
                print("HOTEL UPDATE :: exist hotel with the same name")
                code = '501'
                msg = '酒店已存在'
    if not exist:
        level = request_data['level']
        location = request_data['location']
        intro = request_data['intro']

        hotel = Hotel.objects.get(id=request_data['hotel_id'])

        # xxxxxxxxxxx wait for front end xxxxxxxxxxxxx
        # # save hotel img
        # img = request.FILE.get['url']
        # img_name = hotel_name + '.' + img.name.split('.')[-1]

        # img_content = img.chunks()

        # # only accept jpg
        # # if img_name.split('.')[-1]!= 'jpg':
        # # 	code = '501'
        # # 	msg = '图片格式不正确'
        # # else:
        # path = "/static/images/hotels/%s"%(img_name)
        # # /idx + path: 项目根目录开始找app名 "idx" + path
        # # wb: write & byte 写模式写入二进制数据
        # with open("idx"+path,"wb") as fs:
        # 	for t in img_content:
        # 		fs.write(t)

        # # save hotel img
        # img = request.FILE.get['url']
        # img_name = img.name
        # path = path + '/' + img_name

        # img_content = img.chunks()

        # # only accept jpg
        # # if img_name.split('.')[-1]!= 'jpg':
        # # 	code = '501'
        # # 	msg = '图片格式不正确'
        # # else:
        # with open(path+'.jpg', 'wb') as f:
        # 	for chunk in img_content:
        # 		f.write(chunk)
        # xxxxxxxxxxxxxx wait for front end xxxxxxxxxxxxx
        hotel.name = hotel_name
        hotel.level = level
        hotel.location = location
        hotel.intro = intro
        hotel.save()
        print("hotel update success")

    result = Result(code, msg, {})
    return HttpResponse(json.dumps(result.serialize()),
                        headers={'Access-Control-Allow-Origin': '*'})


# =========================== hotel - room ===================================


# add room
def room_add(request):
    code = '200'
    msg = '添加成功'
    request_data = json.loads(request.body)
    print(request_data)

    # ================ business apply for add room =========================
    if request_data.get('business_id'):
        hotel = Hotel.objects.get(id=request_data['hotel_id'])
        room_type = request_data['room_type']
        # not allow tha same roomtype
        if Room.objects.filter(hotel=hotel, roomtype=room_type).count() != 0:
            code = '501'
            msg = '房型已存在'
        else:
            room = Room.objects.create(hotel=hotel,
                                       roomtype=room_type,
                                       price=request_data['price'],
                                       rest=request_data['amount'],
                                       total=request_data['amount'])
            # create room request record
            RoomRequest.objects.create(
                user=User.objects.get(id=request_data['business_id']),
                room=room,
                status='待审核')
            msg = '申请成功'

    # ================= admin audit room ====================
    elif request_data.get('admin_id'):
        print("admin audit room")
        room = Room.objects.get(id=request_data['room_id'])
        status = ''
        if request_data['status'] == 2:
            status = '已通过'
            print("room audit status: 2==", status)
        elif request_data['status'] == 3:
            status = '已拒绝'
            print("room audit status: 3==", status)
        roomrequest = room.roomrequest
        roomrequest.status = status
        roomrequest.save()
        print("room id = ", room.id, " audit status turn to: ",
              roomrequest.status)
        msg = '审核成功'
    result = Result(code, msg, {})
    return HttpResponse(json.dumps(result.serialize()),
                        headers={'Access-Control-Allow-Origin': '*'})


# get room list
def room_list(request):
    room_list = []
    code = '200'
    msg = '查询成功'
    data = {}

    request_args = json.loads(request.body.decode())
    hotel_id = request_args['hotel_id']

    # get rooms in hotel with hotel_id
    hotel = Hotel.objects.get(id=hotel_id)
    room_ds = Room.objects.filter(hotel=hotel)

    # if there is 'room_type' arg will get specified room
    if request_args.get('room_type'):
        room_ds = room_ds.filter(roomtype=request_args['room_type'])

    if room_ds.count() == 0:
        msg = '没有找到相关房型'
        code = '501'
    else:
        # paginator
        if request_args.get('page_size'):
            page_size = request_args['page_size']
        if request_args.get('page_id'):
            page_id = request_args['page_id']
        pages = Paginator(room_ds, page_size)
        page = pages.get_page(page_id)
        for room in page:
            room_request = RoomRequest.objects.get(room=room)
            room_list.append({
                'room_id': room.id,
                'room_type': room.roomtype,
                'price': room.price,
                'rest': room.rest,
                'amount': room.total,
                'status': room_request.status
            })
        data = {
            'room_list': room_list,
            'page_total': pages.num_pages,
            'item_amount': room_ds.count()
        }
    result = Result(code, msg, data)
    return HttpResponse(json.dumps(result.serialize()),
                        headers={'Access-Control-Allow-Origin': '*'})


def room_delete(request, room_id):
    code = '200'
    msg = '删除成功'
    room = Room.objects.get(id=room_id)

    # canr remove if operation on the room (orders payment)
    if Order.objects.filter(room=room).count() != 0:
        code = '501'
        msg = 'cant remove'
    else:
        room.delete()
    result = Result(code, msg, {})
    return HttpResponse(json.dumps(result.serialize()),
                        headers={'Access-Control-Allow-Origin': '*'})


def room_update(request):
    code = '200'
    msg = '修改成功'

    # request args
    request_data = json.loads(request.body)
    room_type = request_data['room_type']

    # # not allow same type
    # if Room.objects.filter(roomtype=room_type).count()!= 0:
    # 	code = '501'
    # 	msg = '房型已存在'
    # else:
    room_id = request_data['room_id']
    price = request_data['price']
    amount = int(request_data['amount'])
    room = Room.objects.get(id=room_id)
    room.roomtype = room_type
    room.price = price

    # question: how about udpate when some customer booked the room?
    diff = amount - room.total
    room.rest += diff
    room.total = amount
    room.save()
    result = Result(code, msg, {})
    return HttpResponse(json.dumps(result.serialize()),
                        headers={'Access-Control-Allow-Origin': '*'})


# ================================== coupon =======================================


# add coupon template list
def coupon_template_add(request):
    code = '200'
    msg = '添加成功'

    request_data = json.loads(request.body)
    coupon_name = request_data.get('name')
    coupon_discount = request_data.get('discount')
    point_amount = request_data.get('point_amount')

    if CouponTemplate.objects.filter(name=coupon_name).count() != 0:
        code = '501'
        msg = '已有同名优惠券'
    else:
        CouponTemplate.objects.create(name=coupon_name,
                                      discount=coupon_discount,
                                      point_amount=point_amount)
    result = Result(code, msg, {})
    return HttpResponse(json.dumps(result.serialize()),
                        headers={'Access-Control-Allow-Origin': '*'})


def coupon_template_edit(request):
    code = '200'
    msg = '成功'

    request_data = json.loads(request.body)
    coupon_template_id = request_data['id']
    coupon_name = request_data.get('name')
    coupon_discount = request_data.get('discount')
    point_amount = request_data.get('point_amount')

    coupon_template = CouponTemplate.objects.get(id=coupon_template_id)

    coupon_template.name = coupon_name
    coupon_template.discount = coupon_discount
    coupon_template.point_amount = point_amount
    coupon_template.save()

    result = Result(code, msg, {})
    return HttpResponse(json.dumps(result.serialize()),
                        headers={'Access-Control-Allow-Origin': '*'})


def coupon_template_deprecate(request, coupon_template_id):
    coupon_template = CouponTemplate.objects.get(id=coupon_template_id)
    status = coupon_template.deprecated
    coupon_template.deprecated = 1
    coupon_template.save()
    print('coupon template "' + coupon_template.name +
          '" status change from "' + str(status) + '" to "' +
          str(coupon_template.deprecated) + '"')
    result = Result('200', '已废弃', {})
    return HttpResponse(json.dumps(result.serialize()),
                        headers={'Access-Control-Allow-Origin': '*'})


def coupon_template_recover(request, coupon_template_id):
    coupon_template = CouponTemplate.objects.get(id=coupon_template_id)
    status = coupon_template.deprecated
    coupon_template.deprecated = 0
    coupon_template.save()
    print('coupon template "' + coupon_template.name +
          '" status change from "' + str(status) + '" to "' +
          str(coupon_template.deprecated) + '"')
    result = Result('200', '复原优惠券', {})
    return HttpResponse(json.dumps(result.serialize()),
                        headers={'Access-Control-Allow-Origin': '*'})


# get coupon template list
def coupon_template_list(request):
    coupon_list = []
    code = '200'
    msg = '查询成功'
    coupon_ds = CouponTemplate.objects.all()
    if coupon_ds.count() == 0:
        print("coupon_template_list :: no coupon template")
        msg = '没有优惠券模板信息'
        code = '501'
    else:
        for coupon in coupon_ds:
            status = ''
            if coupon.deprecated == 1:
                status = '已废弃'
            if coupon.deprecated == 0:
                status = '可使用'
            coupon_list.append({
                'id': coupon.id,
                'name': coupon.name,
                'discount': coupon.discount,
                'point': coupon.point_amount,
                'status': status
            })
    data = {'coupon_list': coupon_list}
    result = Result(code, msg, data)
    return HttpResponse(json.dumps(result.serialize()),
                        headers={'Access-Control-Allow-Origin': '*'})


# get user's coupon list
def coupon_entity_list(request):
    coupon_list = []
    code = '200'
    msg = '查询成功'
    data = {}

    request_args = json.loads(request.body.decode())
    print(request_args)

    if request_args.get('username'):
        print('username:', request_args['username'])
        username = request_args.get('username')

        user = User.objects.filter(username=username)

        if user.count()==0:
            msg = 'no user matched'
            result = Result(code, msg, data)
            return HttpResponse(json.dumps(result.serialize()), headers={'Access-Control-Allow-Origin': '*'})

        coupon_ds = CouponEntity.objects.filter(user__in=user,
                                                coupon_template__deprecated=0)
        if coupon_ds.count() == 0:
            msg = '没有优惠券'
            # code = '501'
        else:
            # paginator
            page_size = 5
            if request_args.get('page_size'):
                page_size = request_args['page_size']
                print('page size', page_size)
            page_id = 1
            if request_args.get('page_id'):
                page_id = request_args['page_id']
            pages = Paginator(coupon_ds, page_size)
            page = pages.get_page(page_id)
            for coupon in page:
                coupon_list.append({
                    'id': coupon.id,
                    'name': coupon.coupon_template.name,
                    'discount': coupon.coupon_template.discount,
                    'end_time': coupon.end_time,
                    'status': coupon.status
                })
            data = {
                'coupon_list': coupon_list,
                'page_total': pages.num_pages,
                "item_amount": coupon_ds.count()
            }
            print(data)

    result = Result(code, msg, data)
    return HttpResponse(json.dumps(result.serialize()), headers={'Access-Control-Allow-Origin': '*'})


# 兑换优惠券
def coupon_exchange(request):
    code = '200'
    msg = '兑换成功'
    request_data = json.loads(request.body)
    print("coupon_exchange ... args")
    print(request_data)
    user = User.objects.get(id=request_data['user_id'])
    userinfo = user.userinfo
    coupon_template_id = request_data['coupon_template_id']
    coupon_template = CouponTemplate.objects.get(id=coupon_template_id)
    point_amount = coupon_template.point_amount

    # if time is None, it means the coupon is valid forever
    if request_data.get('time'):
        coupon_end_time = request_data['time']
    else:
        coupon_end_time = None

    # update user's point
    if userinfo.point >= point_amount:
        userinfo.point -= point_amount
        userinfo.save()
        # create coupon record
        if coupon_end_time == None:
            coupon_entity = CouponEntity.objects.create(
                user=user, coupon_template=coupon_template)
        else:
            coupon_entity = CouponEntity.objects.create(
                user=user,
                coupon_template=coupon_template,
                end_time=datetime.strptime(coupon_end_time, '%Y-%m-%d %H:%i'))
        # create point outcome record
        Point.objects.create(user=user,
                             couponEntity=coupon_entity,
                             point_amount=point_amount)
    else:
        code = '501'
        msg = '积分不足'

    result = Result(code, msg, {})
    return HttpResponse(json.dumps(result.serialize()),
                        headers={'Access-Control-Allow-Origin': '*'})


# ======================================= orders ===================================


# 用户订单列表
def orders_list(request):
    # default return value
    code = '200'
    msg = '查询成功'
    data = {}
    orders_list = []
    request_data = json.loads(request.body)
    classify_list = request_data.get('classify_list')
    if classify_list==None:
        classify_list = []
    print(request_data)

    # get orders links payment
    if request_data.get('pay_id'):
        pay_record = Pay.objects.get(id=request_data['pay_id'])
        order = pay_record.order
        data = {
            "hotel_name": order.hotel.name,
            "room_num": order.room_num,
            "room_type": order.room.roomtype,
            "name": order.name,
            "id_card": order.id_card,
            "phone": order.phone,
            "email": order.email,
            "note": order.note,
            "time": time_format(order.pre_reachtime, 'H:i'),
            "checkin_date": date_format(order.checkin_date, 'Y-m-d'),
            "checkout_date": date_format(order.checkout_date, 'Y-m-d'),
            "stay_days": order.stay_days,
            "price": order.price
        }
        result = Result(code, msg, data)
        return HttpResponse(json.dumps(result.serialize()),
                            headers={'Access-Control-Allow-Origin': '*'})

    # default page
    current_page = 1
    if request_data.get('page_id'):
        print('page id', current_page)
        current_page = request_data['page_id']
    page_size = 5
    if request_data.get("page_size"):
        page_size = request_data['page_size']

    orders_ds = Order.objects.all()
    # get hotel related orders (business logic)
    if request_data.get('hotel_id'):
        hotel = Hotel.objects.get(id=request_data['hotel_id'])
        classify_list = request_data.get('classify_list')
        # if classify_list != None:
        orders_ds = Order.objects.filter(
                hotel=hotel,
                status__in=classify_list)
        # else:
        #     orders_ds = Order.objects.filter(hotel=hotel)
    # get user related orders
    if request_data.get('user_id'):
        user = User.objects.get(id=request_data['user_id'])
        classify_list = request_data.get('classify_list')
        # if classify_list!= None:
        orders_ds = Order.objects.filter(
                user=user, status__in=classify_list)
        # else:
        #     orders_ds = Order.objects.filter(user=user)
    if request_data.get('hotel_name'):
        classify_list = request_data.get('classify_list')
        # if classify_list!= None:
        orders_ds = Order.objects.filter(
                hotel__name__contains=request_data.get('hotel_name'),
                status__in=classify_list)
        # else:
        #     orders_ds = Order.objects.filter(
        #         hotel__name__contains=request_data.get('hotel_name'))

    # orders not found
    if orders_ds.count() == 0:
        # code = '501'
        msg = '没有订单'
    # orders paginator
    else:

        # only get online record ( role=user )
        if request_data.get('type')=='online':
            hotel = Hotel.objects.get(id=request_data['hotel_id'])
            orders_ds = Order.objects.filter(hotel=hotel, user__role='用户', status__in=classify_list)
            # if request_data.get('status'):
            #     orders_ds = Order.objects.filter(hotel=hotel, user__role='商家', status=request_data.get('status'))
            pages = Paginator(orders_ds, page_size)
            page = pages.get_page(current_page)
            for order in page:
                order_type = '线上'
                if order.user.role == "商家":
                    order_type = '线下'
                orders_list.append({
                    'id': order.id,
                    'hotel_name': order.hotel.name,
                    "room_num": order.room_num,
                    'room_type': order.room.roomtype,
                    'price': order.price,
                    'status': order.status,
                    'order_type': order_type,
                    "id_card": order.id_card,
                    "name": order.name,
                    "phone": order.phone,
                    "email": order.email,
                    "note": order.note,
                    "time": time_format(order.pre_reachtime, 'H:i'),
                    "checkin_date": date_format(order.checkin_date, 'Y-m-d'),
                    "checkout_date": date_format(order.checkout_date, 'Y-m-d'),
                    "stay_days": order.stay_days,
                })
            data = {
                "order_list": orders_list,
                "page_total": pages.num_pages,
                "item_amount": orders_ds.count()
            }
            print(data)
        elif request_data.get('type')=='offline':
            hotel = Hotel.objects.get(id=request_data['hotel_id'])
            orders_ds = Order.objects.filter(hotel=hotel, user__role='商家', status__in=classify_list)
            # if request_data.get('status'):
            #     orders_ds = Order.objects.filter(hotel=hotel, user__role='商家', status=request_data.get('status'))

            pages = Paginator(orders_ds, page_size)
            page = pages.get_page(current_page)
            for order in page:
                order_type = '线上'
                if order.user.role == "商家":
                    order_type = '线下'
                orders_list.append({
                    'id': order.id,
                    'hotel_name': order.hotel.name,
                    "room_num": order.room_num,
                    'room_type': order.room.roomtype,
                    'price': order.price,
                    'status': order.status,
                    'order_type': order_type,
                    "id_card": order.id_card,
                    "name": order.name,
                    "phone": order.phone,
                    "email": order.email,
                    "note": order.note,
                    "time": time_format(order.pre_reachtime, 'H:i'),
                    "checkin_date": date_format(order.checkin_date, 'Y-m-d'),
                    "checkout_date": date_format(order.checkout_date, 'Y-m-d'),
                    "stay_days": order.stay_days,
                })
            data = {
                "order_list": orders_list,
                "page_total": pages.num_pages,
                "item_amount": orders_ds.count()
            }
            print(data)
        else:
            pages = Paginator(orders_ds, page_size)
            page = pages.get_page(current_page)
            for order in page:
                order_type = '线上'
                if order.user.role == "商家":
                    order_type = '线下'
                orders_list.append({
                    'id': order.id,
                    'hotel_name': order.hotel.name,
                    "room_num": order.room_num,
                    'room_type': order.room.roomtype,
                    'price': order.price,
                    'status': order.status,
                    'order_type': order_type,
                    "id_card": order.id_card,
                    "name": order.name,
                    "phone": order.phone,
                    "email": order.email,
                    "note": order.note,
                    "time": time_format(order.pre_reachtime, 'H:i'),
                    "checkin_date": date_format(order.checkin_date, 'Y-m-d'),
                    "checkout_date": date_format(order.checkout_date, 'Y-m-d'),
                    "stay_days": order.stay_days,
                })
            data = {
                "order_list": orders_list,
                "page_total": pages.num_pages,
                "item_amount": orders_ds.count()
            }
            print(data)
    result = Result(code, msg, data)
    return HttpResponse(json.dumps(result.serialize()),
                        headers={'Access-Control-Allow-Origin': '*'})


def order_status_update(request):
    code = 200
    msg = '取消成功'
    data = {}

    request_args = json.loads(request.body.decode())
    order_id = request_args['order_id']
    status = request_args['status']

    order = Order.objects.get(id=order_id)
    user = order.user
    pay_record = order.pay

    # update order's status
    order.status = status
    order.save()

    if status == '已取消':
        # update related payment record
        pay_record.status = '已取消'
        pay_record.save()
    elif status == '入住':
        # create checkin record
        Checkin.objects.create(user=user, order=order)
    elif status == '退房':
        # create checkout record
        Checkout.objects.create(user=user, order=order)
    # elif status == '续房':
    # create continew record
    # link old order
    # link new payment

    result = Result(code, msg, data)
    return HttpResponse(json.dumps(result.serialize()))


# 取消订单
def order_cancel(request, order_id):
    print("order_cancel ...")
    code = 200
    msg = '取消成功'
    data = {}
    order = Order.objects.get(id=order_id)
    order.status = '已取消'
    order.save()
    print("cancel order success, statu:", order.status)
    result = Result(code, msg, data)
    return HttpResponse(json.dumps(
        result.serialize()))  # ah ??? no headers ???


def order_update(request, order_id):
    code = '200'
    msg = '更新成功'
    order = Order.objects.get(id=order_id)
    print("update order status ...")
    order.status = '已完成'
    order.save()
    print("saved ... order status =", order.status)
    result = Result(code, msg, {})
    return HttpResponse(json.dumps(result.serialize()),
                        headers={'Access-Control-Allow-Origin': '*'})


# ========================= comment ==============================


# add
def comment_add(request):
    code = '200'
    msg = '添加成功'
    request_data = json.loads(request.body)
    print("---------- user add comment --------")
    print(request_data)

    user = User.objects.get(id=request_data['user_id'])
    order = Order.objects.get(id=request_data['order_id'])
    comment = Comment.objects.create(user=user,
                                     order=order,
                                     content=request_data['context'])

    # update order status
    order.status = '已评价'
    order.save()
    print('user add content:', comment.content)
    result = Result(code, msg, {})
    return HttpResponse(json.dumps(result.serialize()),
                        headers={'Access-Control-Allow-Origin': '*'})


# delete
def comment_delete(request):
    code = '200'
    msg = '删除成功'
    comment_id = request.GET.get('comment_id')

    record = Comment.objects.get(id=comment_id)
    record.delete()
    result = Result(code, msg, {})
    return HttpResponse(result.serialize(),
                        headers={'Access-Control-Allow-Origin': '*'})


# get user/hotel related comments
def comment_list(request):
    code = '200'
    msg = '查询成功'
    data = {}
    comment_list = []
    request_data = json.loads(request.body)

    current_page = 1
    if request_data.get('page_id'):
        current_page = request_data['page_id']
    page_size = 5
    if request_data.get('page_size'):
        page_size = request_data['page_size']

    comment_ds = Comment.objects.all()
    # get user related comments
    if request_data.get('user_id'):
        user = User.objects.get(id=request_data['user_id'])
        comment_ds = Comment.objects.filter(user=user)
    # get hotel related comments
    if request_data.get('hotel_id'):
        hotel = Hotel.objects.get(id=request_data['hotel_id'])
        comment_ds = Comment.objects.filter(order__hotel=hotel)

    # no orders found
    if comment_ds.count() == 0:
        code = '501'
        msg = '没有相关记录'
    # comment paginetor
    else:
        pages = Paginator(comment_ds, page_size)
        page = pages.get_page(current_page)
        for comment in page.object_list:
            time = time_format(comment.time, 'H:i')
            print("comment content: ", comment.content)
            comment_list.append({
                "id": comment.id,
                "username": comment.user.username,
                "content": comment.content,
                "time": time
            })
        data = {
            "comment_list": comment_list,
            "page_total": pages.num_pages,
            "item_amount": comment_ds.count()
        }
    result = Result(code, msg, data)
    return HttpResponse(json.dumps(result.serialize()),
                        headers={'Access-Control-Allow-Origin': '*'})


# ======================== rate ==============================

def num_classified_order(request):
    result = Result('200','',{})
    request_data = Request(request)
    arg_status = request_data.get('status')
    business =  User.objects.get(id=request_data.get('business_id'))

    order_ds = Order.objects.filter(status__in=arg_status, hotel__admin=business)
    if order_ds.count()==0:
        result.msg = 'no data'
        return result.http_response
    result.data = {'amount': order_ds.count()}
    return result.http_response()

def user_register_num(request):
    result = Result('200', 'add news ojbk', {})
    numlist = []
    register_num = UserRegisterNum.objects.all()
    total = User.objects.filter(role='用户').count()

    for item in register_num:
        numlist.append({
            'day': date_format(item.day, 'Y-m-d'),
            'amount': item.amount
        })

    result.data = {'list': numlist, 'total': total}
    return result.http_response()


def daily_income_list(request):
    code = '200'
    msg = ''
    data = {}
    income_list = []

    request_data = Request(request)
    page_id = request_data.get('page_id')
    page_size = request_data.get('page_size')

    income_ds = None

    if request_data.get('hotel_name'):
        hotel_name = request_data.get('hotel_name')
        income_ds = DailyIncome.objects.filter(hotel__name__contains=hotel_name)
    elif request_data.get('hotel_id'):
        hotel_id = request_data.get('hotel_id')
        income_ds = DailyIncome.objects.filter(hotel__id=hotel_id)
    else:
        income_ds = DailyIncome.objects.all()
    pages = Pages(income_ds, page_size)
    if pages.is_exists():
        for item in pages.get(page_id):
            income_list.append({
                'day': date_format(item.day, 'Y-m-d'),
                'income': item.income,
                'hotel_name': item.hotel.name
            })
        data = {'income_list': income_list, 'page_total': pages.page_total, 'item_amount': income_ds.count()}

    result = Result(code, msg, data)
    return result.http_response()


def area_order_num(request):
    code = '200'
    msg = ''
    data = {}
    area_list = []

    area_ds = AreaOrderNum.objects.all()
    for item in area_ds:
        area_list.append({'area': item.area, 'amount': item.count})
    data = {'list': area_list}
    result = Result(code, msg, data)
    return HttpResponse(json.dumps(result.serialize()),
                        headers={'Access-Control-Allow-Origin': '*'})


# 统计不同地区的酒店预定率
def rate_order_area(request):
    code = '200'
    msg = ''
    data = {}
    ords = Order.objects.exclude(status='已取消')
    for i in ords:
        print(i.id, i.status)
    # orders total amount
    total = ords.count()
    print(total)

    if total == 0:
        msg = '无法统计'
    # 一个保存字典的列表，字典，保存地区和预订量，
    # dic = { '酒店地址': (int)预订数量}
    # ======== 升级喽！！！增加比率 ===============
    # dic = {
    # 	'location': {
    # 		'order_num': int,
    # 		'rate': float
    # 	}
    # }
    # ========= rate deprecated!!! ============
    else:
        areaList = []

        for o in ords:
            # 地区是否重复
            reflag = False
            for i in range(0, len(areaList)):
                if o.hotel.location == areaList[i]['location']:
                    reflag = True
                    # 重复 统计区域预订量
                    orderNum = areaList[i].pop('order_num')
                    orderNum += 1
                    areaList[i]['order_num'] = orderNum
                    # print('repeat. ', areaList[i]['location'], '+1')
            # 不重复 预订量初始化为1
            if reflag == False:
                areaList.append({'location': o.hotel.location, 'order_num': 1})
                # print('no repeat, init ',o.hotel.location)

        # 有 echarts 就 ojbk
        # pp!
        # 计算占比率
        for i in areaList:
            i['order_rate'] = i['order_num'] / total
        data = {'rate_order_area_list': areaList}
    result = Result(code, msg, data)
    return HttpResponse(json.dumps(result.serialize()),
                        headers={'Access-Control-Allow-Origin': '*'})


# =========== news =============


def news_add(request):
    print('-------- news add -------------')
    request_args = json.loads(request.body.decode())
    print('news add :: args', request_args)
    title = request_args['title']
    content = request_args['content']
    News.objects.create(title=title, content=content)
    print('news saved')
    result = Result('200', 'add news ojbk', {})
    return HttpResponse(json.dumps(result.serialize()))


def news_list(request):
    code = '200'
    msg = 'ojbk'
    data = {}
    print('----- news list ------------')
    news_ds = News.objects.all()
    if news_ds.count() == 0:
        code = '501'
        msg = 'no data'
    else:
        news_list = []
        for news in news_ds:
            news_list.append({
                'id': news.id,
                'title': news.title,
                'content': news.content
            })
        data = {'news_list': news_list}
    result = Result(code, msg, data)
    return HttpResponse(json.dumps(result.serialize()))


def news_delete(request, news_id):
    news = News.objects.get(id=news_id)
    news.delete()
    return HttpResponse(json.dumps(Result('200', 'ojbk', {}).serialize()))




# pay route list
def pay_route_list(request):
    code = '200'
    msg = 'ojbk'
    data = {}
    pay_route_list = []
    pay_route = PayRoute.objects.all()
    for item in pay_route:
        pay_route_list.append({'name': item.name, 'desc': item.desc})
    data = pay_route_list
    result = Result(code, msg, data)
    return HttpResponse(json.dumps(result.serialize()))


def pay_route_add(request):
    code = '200'
    msg = 'ojbk'
    data = {}

    request_args = json.loads(request.body.decode())
    name = request_args['name']
    desc = request_args['desc']

    PayRoute.objects.create(name=name, desc=desc)
    result = Result(code, msg, data)
    return HttpResponse(json.dumps(result.serialize()))


def hotel_rank_list(request):
    code = '200'
    msg = 'ojbk'
    data = {}
    hotel_rank_list = []
    hotel_rank = HotelRank.objects.all()
    for item in hotel_rank:
        hotel = item.hotel
        hotel_rank_list.append({'hotelname': hotel.name, 'hotel_id': hotel.id})
        data = hotel_rank_list
    result = Result(code, msg, data)
    return HttpResponse(json.dumps(result.serialize()))


def hotel_rank_add(request, hotel_id):
    code = '200'
    msg = 'ojbk'
    data = {}
    # cant add rank if there is 5 hotel rank items

    if Hotel.objects.all().count() == 5:
        code = '501'
        msg = 'more than 5'
    else:
        hotel = Hotel.objects.get(id=hotel_id)
        HotelRank.objects.create(hotel=hotel)
    result = Result(code, msg, data)
    return HttpResponse(json.dumps(result.serialize()))


def hotel_rank_delete(request, hotel_id):
    code = '200'
    msg = 'ojbk'
    data = {}

    hotel = Hotel.objects.get(id=hotel_id)
    hotel_rank_item = HotelRank.objects.get(hotel=hotel)
    hotel_rank_item.delete()

    result = Result(code, msg, data)
    return HttpResponse(json.dumps(result.serialize()))


def hotel_recommend_list(request):
    code = '200'
    msg = 'ojbk'
    data = {}
    hotel_recommend_list = []
    hotel_recommend = HotelRecommend.objects.all()
    for item in hotel_recommend:
        hotel = item.hotel
        hotel_recommend_list.append({
            'hotelname': hotel.name,
            'hotel_id': hotel.id,
            'level': hotel.level,
            'location': hotel.location,
            'intro': hotel.intro,
            'min_price': hotel.min_price
        })
        data = hotel_recommend_list
    result = Result(code, msg, data)
    return HttpResponse(json.dumps(result.serialize()))


def hotel_recommend_add(request, hotel_id):
    code = '200'
    msg = 'ojbk'
    data = {}

    # cant add rank if there is 5 hotel rank items
    if HotelRecommend.objects.all().count()>=5:
        code = '501'
        msg = 'hotel_recommend_list amount >5'

    else:
        hotel = Hotel.objects.get(id=hotel_id)

        # the hotel has been recommended
        if HotelRecommend.objects.filter(hotel=hotel).count()!=0:
            code = '502'
            msg = '酒店已被推荐'
        else:
            HotelRecommend.objects.create(hotel=hotel)
    result = Result(code, msg, data)
    return HttpResponse(json.dumps(result.serialize()))


def hotel_recommend_delete(request, hotel_id):
    code = '200'
    msg = 'ojbk'
    data = {}

    hotel = Hotel.objects.get(id=hotel_id)
    hotel_recommend_item = hotel.hotelrecommend
    hotel_recommend_item.delete()

    result = Result(code, msg, data)
    return HttpResponse(json.dumps(result.serialize()))

# hotel activity

def activity_apply(request):
    request_data = Request(request)
    result = Result('200', '', {})

    user_id = request_data.get('user_id')
    business = User.objects.get(id=user_id)
    hotel = Hotel.objects.get(admin=business, hotelrequest__status='已通过')

    # check user role
    if User.objects.filter(id=user_id, role='商家').count() == 0:
        result.msg = 'no matched user'
        return result.http_response()

    if HotelActivityRequest.objects.filter(hotel__admin=business).count() != 0:
        print('already apply for activity')
        result.code = '501'
        result.msg = 'already apply for activity'
        return result.http_response()
    # business apply for activity
    HotelActivityRequest.objects.create(hotel=hotel)
    result.msg ='success'
    return result.http_response()

def activity_apply_list(request):
    request_data = Request(request)

    page_size = 5
    if request_data.get('page_size'):
        page_size = request_data.get('page_size')
    page_id = 1
    if request_data.get('page_id'):
        page_id = request_data.get('page_id')


    result = Result('200', '', {})
    apply_list = []

    hotel_activity_request_ds = HotelActivityRequest.objects.all()
    if hotel_activity_request_ds.count() == 0:
        result.msg = 'no hotel apply for activity'
        return result.http_response()
    
    pages = Pages(hotel_activity_request_ds, page_size)
    page = pages.get(page_id)
    for item in page:
        hotel = item.hotel
        apply_list.append({
            'id': item.id,
            'hotelname': hotel.name,
            'status': item.status,
            'level': hotel.level,
            'location': hotel.location,
            'hotel_id': hotel.id,
           'min_price': hotel.min_price
        })
    result.data = {'apply_list': apply_list, 'page_total': pages.page_total,
                   'item_amount': hotel_activity_request_ds.count()}
    return result.http_response()

def activity_audit(request):
    request_data = Request(request)
    result = Result('200', '', {})

    user_id = request_data.get('user_id')
    apply_id = request_data.get('apply_id')
    status = request_data.get('status')

    # user role check
    if User.objects.filter(id=user_id, role='管理员').count()==0:
        result.msg = 'role != admin'
        result.code = '501'
        return result.http_response()

    hotel_activity_request = HotelActivityRequest.objects.get(id=apply_id)

    # create activity if admin pass audit
    hotel_activity_request.status = status
    hotel_activity_request.save()
    if status == '已通过':
        if HotelActivity.objects.filter(hotelrequest=hotel_activity_request).count() == 0:
            HotelActivity.objects.create(hotelrequest=hotel_activity_request)
    return result.http_response()

# delete activity & update activity reqeust status
def activity_delete(request):
    request_data = Request(request)
    result = Result('200', '', {})

    activity_id = request_data.get('activity_id')

    activity = HotelActivity.objects.get(id=activity_id)
    activity_request = activity.hotelrequest

    activity.delete()
    activity_request.status = '已结束'

    return result.http_response()

def activity_list(request):
    request_data = Request(request)
    result = Result('200', '', {})

    page_size = 5
    if request_data.get('page_size'):
        page_size = request_data.get('page_size')
    page_id = 1
    if request_data.get('page_id'):
        page_id = request_data.get('page_id')

    activity_list = []

    activity_ds = HotelActivity.objects.filter(hotelrequest__status='已通过')

    if activity_ds.count() == 0:
        result.msg = 'no activity'
        return result.http_response()
    
    pages = Pages(activity_ds, page_size)
    page = pages.get(page_id)
    for item in page:
        hotel = item.hotelrequest.hotel
        activity_list.append({
            'id': item.id,
            'hotelname': hotel.name,
            'level': hotel.level,
            'location': hotel.location,
            'hotel_id': hotel.id,
            'min_price': hotel.min_price
       })
    result.data = {'activity_list': activity_list, 'page_total': pages.page_total,
                   'item_amount': activity_ds.count()}
    return result.http_response()


# 返回码 res.code:
# - '200' 参加成功
# - '501' 参加失败
def user_activity_join(request):
    request_data = Request(request)
    result = Result('200', '', {})
    user_id = request_data.get('user_id')
    activity_id = request_data.get('activity_id')
    user = User.objects.get(id=user_id)
    activity = HotelActivity.objects.get(id=activity_id)
    print('user id', user.id)
    print(('activity id', activity.id))

    if HotelActivityUserJoin.objects.filter(user=user, hotelactivity=activity).count() != 0:
        print(HotelActivityUserJoin.objects.filter(user=user, hotelactivity=activity)[0].id)
        result.msg = 'user has joined'
        result.code = '501'
        return result.http_response()
    
    user_joined = HotelActivityUserJoin.objects.create(user=user, hotelactivity=activity)

    # user point + 100
    # 1. add Point record
    Point.objects.create(user=user, activity=user_joined, point_amount=100)
    # 2. update userinfo point_amount
    userinfo = user.userinfo
    userinfo.point += 100
    userinfo.save()

    # add usernum of joined activity
    if UserNumInHotelActivity.objects.filter(hotelactivity=activity).count()==0:
        UserNumInHotelActivity.objects.create(hotelactivity=activity)
    else: # add user num in activity
        user_num_in_activity = user_joined.hotelactivity.usernuminhotelactivity
        user_num_in_activity.count += 1
    result.msg = 'success'
    return result.http_response()

def user_activity_list(request):
    request_data = Request(request)
    result = Result('200', '', {})

    activity_user_joined_ds = HotelActivityUserJoin.objects.all()

    if request_data.get('user_id')!='':
        user_id = request_data.get('user_id')
        user = User.objects.get(id=user_id)
        activity_user_joined_ds = HotelActivityUserJoin.objects.filter(user=user)
    activity_list = []

    page_size = 5
    if request_data.get('page_size'):
        page_size = request_data.get('page_size')
    page_id = 1
    if request_data.get('page_id'):
        page_id = request_data.get('page_id')


    if activity_user_joined_ds.count() == 0:
        result.msg = 'user has no joined activity'
        return result.http_response()
    
    pages = Pages(activity_user_joined_ds, page_size)
    page = pages.get(page_id)

    for item in page:
        activity = item.hotelactivity
        hotel = activity.hotelrequest.hotel
        activity_list.append({
            'hotel_id': hotel.id,
            'activity_id': activity.id,
            'hotelname': hotel.name,
            'username': item.user.username,
            #@todo: 时间格式化
            'join_time': item.join_time.strftime('%Y-%m-%d %H:%M:%S')
    })
    result.data = {'activity_list': activity_list, 'page_total': pages.page_total,
                   'item_amount': activity_user_joined_ds.count()}
    return result.http_response()

def activity_user_count(request):
    result = Result('200', '', {})

    num_list = []

    activity_user_num_ds = UserNumInHotelActivity.objects.all()

    if activity_user_num_ds.count() == 0:
        result.msg = 'no data'
        return result.http_response()
    
    for item in activity_user_num_ds:
        num_list.append({
            'activity_id': item.hotelactivity.id,
            'hotel_name': item.hotelactivity.hotelrequest.hotel.name,
            'num': item.count
        })

    result.data = num_list
    return result.http_response()
